using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UMC.Web;
using UMC.Web.UI;
using UMC.WorkFlow.Entities;

namespace UMC.WorkFlow
{
    [Apiumc("WorkFlow", "Design", Auth = WebAuthType.Admin, Desc = "工作流设计")]
    public class DesignActivity : UMC.Web.WebActivity
    {
        internal static readonly Type Nullable = typeof(Nullable<>);
        protected TaskInstance taskInstance;
        protected Object DesignValue;
        protected String DesignId;
        void Setting(Object value)
        {
            var args = this.Context.Request.Arguments;
            var request = this.Context.Request;
            var type = value.GetType();
            var Property = this.AsyncDialog("Property", g =>
            {

                //UIDesignAttribute attribute = (UIDesignAttribute)type.GetCustomAttributes(typeof(UIDesignAttribute), false)[0];
                var form = UMC.Web.UISection.Create(new UITitle("流程设置"));
                form.AddCell("类型", value.GetType().Name);
                if (value is Line)
                {
                    form.Title.Title = "审批路线";
                    var line = (Line)value;
                    var fshape = taskInstance.Shapes.Find(s => s.Id == line.FromId);
                    var tshape = taskInstance.Shapes.Find(s => s.Id == line.ToId);
                    form.AddCell("标识", line.Id).AddCell("开始结点", String.Format("{1}-{0}", line.FromId, fshape.Text))
                          .AddCell("结尾结点", String.Format("{1}-{0}", line.ToId, tshape.Text));
                }
                else if (value is Shape)
                {
                    form.Title.Title = "审批结点";
                    var line = (Shape)value;
                    form.AddCell("标识", line.Id).AddCell("标题", line.Text
                        , new UIClick(request, new WebMeta(args.GetDictionary()).Put(g, "Text")));
                }
                else if (value is InduceLine)
                {
                    form.Title.Title = "驳回线路";
                    var line = (InduceLine)value;
                    form.AddCell("标识", line.Id);
                }
                else if (value is Responder)
                {
                    form.Title.Title = "服务组件";
                    var line = (Responder)value;
                    form.AddCell("标识", line.Id).AddCell("标题", line.Text
                        , new UIClick(request, new WebMeta(args.GetDictionary()).Put(g, "Text")));

                }
                var ui = form.NewSection();
                System.Reflection.PropertyInfo[] propertys = type.GetProperties();
                Array.Sort<PropertyInfo>(propertys, (t, t1) =>
                {
                    return String.Compare(t.Name, t1.Name);
                });
                for (int i = 0; i < propertys.Length; i++)
                {
                    var propery = new WebMeta();
                    var pty = propertys[i];
                    switch (pty.Name)
                    {
                        case "Id":
                        case "ToId":
                        case "FromId":
                        case "Text":
                            continue;
                    }
                    var objs = pty.GetCustomAttributes(typeof(DesignAttribute), false);
                    if (objs.Length > 0)
                    {

                        var attr = objs[0] as DesignAttribute;
                        if (pty.PropertyType.IsPrimitive || pty.PropertyType == typeof(String) || pty.PropertyType.IsEnum || (pty.PropertyType.IsGenericType && Nullable == pty.PropertyType.GetGenericTypeDefinition()


                            ))
                        {
                            var pv = pty.GetValue(value);
                            if (pv == null)
                            {
                                ui.AddCell(attr.Caption, "[未设置]", new UIClick(request, new WebMeta(args.GetDictionary()).Put(g, pty.Name)));
                            }
                            else
                            {
                                var strV = pv.ToString();
                                switch (attr.ArgumentType)
                                {
                                    case ArgumentType.NVSource:
                                        var ts = attr.ArgumentValue.Split(',');
                                        var nv = new Hashtable();
                                        for (var l = 0; l < ts.Length; l += 2)// in attr.ArgumentValue.Split(','))
                                        {
                                            if (l + 1 < ts.Length)
                                            {
                                                nv[ts[l + 1]] = ts[l];
                                            }
                                            else
                                            {
                                                nv[ts[l]] = ts[l];
                                            }
                                        }
                                        if (nv.ContainsKey(pv.ToString()))
                                        {

                                            ui.AddCell(attr.Caption, String.Format("{0}", nv[pv.ToString()]), new UIClick(request, new WebMeta(args.GetDictionary()).Put(g, pty.Name)));
                                        }
                                        else
                                        {
                                            ui.AddCell(attr.Caption, "[值不在列表]", new UIClick(request, new WebMeta(args.GetDictionary()).Put(g, pty.Name)));

                                        }

                                        break;
                                    case ArgumentType.Shape:
                                        if (strV == "ALL")
                                        {
                                            ui.AddCell(attr.Caption, "所有结点", new UIClick(request, new WebMeta(args.GetDictionary()).Put(g, pty.Name)));
                                        }
                                        else
                                        {
                                            var shape = taskInstance.Shapes.Find(s => s.Id == strV);
                                            if (shape != null)
                                            {
                                                ui.AddCell(attr.Caption, String.Format("({0}){1}", shape.Id, shape.Text), new UIClick(request, new WebMeta(args.GetDictionary()).Put(g, pty.Name)));
                                            }
                                            else
                                            {
                                                ui.AddCell(attr.Caption, String.Format("({0})[节点错误]", strV, shape.Text), new UIClick(request, new WebMeta(args.GetDictionary()).Put(g, pty.Name)));

                                            }

                                        }
                                        break;
                                    case ArgumentType.Line:
                                        if (strV == "ALL")
                                        {

                                            ui.AddCell(pty.Name, "所有线路", new UIClick(request, new WebMeta(args.GetDictionary()).Put(g, pty.Name)));
                                        }
                                        else
                                        {
                                            var shape = taskInstance.Lines.Find(s => s.Id == strV);
                                            if (shape != null)
                                            {
                                                ui.AddCell(pty.Name, String.Format("({0}){1}", shape.Id, shape.Text), new UIClick(request, new WebMeta(args.GetDictionary()).Put(g, pty.Name)));
                                            }
                                            else
                                            {
                                                ui.AddCell(pty.Name, String.Format("({0})[线路错误]", strV, shape.Text), new UIClick(request, new WebMeta(args.GetDictionary()).Put(g, pty.Name)));

                                            }

                                        }
                                        break;
                                    default:
                                        var pValue = String.Format("{0}", pv);
                                        if (attr.IsValueToText && value is IDesignValueToText)
                                        {
                                            pValue = ((IDesignValueToText)value).GetText(pty.Name, pv);
                                        }
                                        ui.AddCell(attr.Caption, pValue, new UIClick(request, new WebMeta(args.GetDictionary()).Put(g, pty.Name)));
                                        break;
                                }
                            }

                        }
                        else
                        {
                            ui.AddCell(attr.Caption
                        , new UIClick(request, new WebMeta(args.GetDictionary()).Put(g, pty.Name)));

                        }
                    }
                }

                UICell cell = UICell.Create("UI", new UMC.Web.WebMeta().Put("text", "删除").Put("Icon", "\uf014").Put("click"
                        , new UIClick(request, new WebMeta(args.GetDictionary()).Put(g, "Delete"))));
                cell.Style.Name("text", new UIStyle().Color(0xf00));


                if (value is Shape)
                {
                    var rlines = taskInstance.Induces.FindAll(rg => rg.FromId == DesignId);



                    var lui = form.NewSection()
                      .AddCell('\uF06e', "表单可见", "设置"
                      , new UIClick(request.Model, "CheckControl", new UMC.Web.WebMeta().Put("Id", DesignId).Put("Task", taskInstance.TaskId)))
                      .AddCell('\uf024', "审批按钮", "设置", new UIClick(request.Model, "Button", new UMC.Web.WebMeta().Put("Id", DesignId).Put("Task", taskInstance.TaskId))
                     )

                      .NewSection();

                    foreach (var r in rlines)
                    {
                        var sa = taskInstance.Shapes.Find(sg => sg.Id == r.ToId);
                        if (sa != null)
                        {

                            UICell cell2 = UICell.Create("UI", new UMC.Web.WebMeta().Put("text", r.Text, "value", String.Format("驳回到{0}", sa.Text)).Put("Icon", "\uf112"));
                            //cell.Style.Name("text", new UIStyle().Color(0xf00));

                            //lui.AddCell('\uf112', r.Text, String.Format("驳回到{0}", sa.Text));
                            lui.Delete(cell2, new UIEventText("删除").Click(new UIClick(request, new WebMeta(args.GetDictionary()).Put(g, "Delete").Put("Id", r.Id))));
                        }

                    }
                    lui.AddCell('\uf067', "驳回指定节点", ""
                      , new UIClick(request.Model, "Subassembly", new UMC.Web.WebMeta().Put("FromId", DesignId).Put("Task", taskInstance.TaskId).Put("Type", typeof(InduceLine).FullName))
                      )
                      .NewSection();
                    //var UIfooter = UIFooterButton.Create();
                    //UIfooter.Title(cl.Caption);
                    //UIfooter.Button(new UIEventText("驳回跳转").Click(new UMC.Web.UIClick(new WebMeta(argsValue).Put(g, cl.ItemId))));
                    //lui.Add(UIfooter);
                    lui.NewSection().Add(cell);


                }
                else
                {
                    form.NewSection().Add(cell);
                }
                form.SendTo("WorkFlow.Page", this.Context, "WorkFlow.Design");
            });
            if (Property == "Delete")
            {
                //if ((value is InduceLine) == false)
                //    this.AsyncDialog("Confirm", g => new UMC.Web.UIConfirmDialog("确认删除吗"));
                if (value is Line)
                {
                    this.taskInstance.Lines.Remove((Line)value);
                }
                else if (value is Shape)
                {
                    var shape = (Shape)value;
                    if(shape.Id== "spe0")
                    {
                        this.Prompt("开始结点不能删除");
                    }
                    this.taskInstance.Lines.RemoveAll(g => g.ToId == shape.Id || g.FromId == shape.Id);
                    this.taskInstance.Induces.RemoveAll(g => g.ToId == shape.Id || g.FromId == shape.Id);

                    this.taskInstance.Shapes.Remove((Shape)value);
                }
                else if (value is InduceLine)
                {
                    this.taskInstance.Induces.Remove((InduceLine)value);
                }
                else if (value is Responder)
                {
                    this.taskInstance.Registes.Remove((Responder)value);

                }
                var json = UMC.Data.JSON.Serialize(this.taskInstance, true);
                TaskManager.Design(this.taskInstance, this.Context.Token.Username);


                DataFactory.Instance().Delete(new TaskStaff
                {
                    DesignKey = DesignId,
                    TaskId = taskInstance.TaskId,
                });//.Entities.Delete();
                if (value is InduceLine)
                {
                    return;
                }
                else
                {
                    this.Context.Send("WorkFlow.Page", false);
                    this.Context.Send("WorkFlow.Del", new WebMeta().Put("Task", UMC.Data.JSON.Expression(json)), true);

                }

            }
            System.Reflection.PropertyInfo property = type.GetProperty(Property);
            this.DesignValue = value;

            var ob2js = property.GetCustomAttributes(typeof(DesignAttribute), false);
            if (ob2js.Length > 0)
            {
                var attr = ob2js[0] as DesignAttribute;
                var va2 = this.SetValue(property, property.GetValue(value), attr);
                property.SetValue(value, va2);
                var json = UMC.Data.JSON.Serialize(this.taskInstance, true);
                TaskManager.Design(this.taskInstance, this.Context.Token.Username);
                if (property.Name == "Text")
                {
                    this.Context.Send("WorkFlow.Design", new WebMeta().Put("Task", UMC.Data.JSON.Expression(json)), true);
                }
                else
                {
                    this.Context.Send("WorkFlow.Design", true);
                }
            }
            else
            {
                this.Prompt("非设计属性");
            }
        }


        protected virtual object SetValue(System.Reflection.PropertyInfo property, object value, DesignAttribute attr)
        {
            var name = property.Name;
            switch (attr.ArgumentType)
            {
                case ArgumentType.Command:
                    this.Context.Response.Redirect(this.Context.Request.Model, attr.ArgumentValue, this.Context.Request.Arguments, true);
                    break;
                case ArgumentType.Select:
                    return UMC.Data.Reflection.Parse(this.AsyncDialog(name, this.Context.Request.Model, attr.ArgumentValue), property.PropertyType);
                case ArgumentType.Line:
                    return this.AsyncDialog(name, g =>
                    {
                        var ts = new List<Line>
                        {
                            new UMC.WorkFlow.Subassembly.Line() { Id = "ALL", Text = "所有审批线" }
                        };
                        var gl = UIDialog.Create(new UIGridDialog.Header("Id", 0).PutField("Text", "名称").PutField("Id", "标志"), ts.ToArray());
                        gl.Title = "审批线";
                        return gl;
                    });
                case ArgumentType.Shape:
                    return this.AsyncDialog(name, g =>
                    {
                        var ts = new List<Shape>
                        {
                            new UMC.WorkFlow.Subassembly.Shape() { Id = "ALL", Text = "所有节点" }
                        };
                        ts.AddRange(this.taskInstance.Shapes);

                        var gl = UIDialog.Create(new UIGridDialog.Header("Id", 0).PutField("Text", "名称").PutField("Id", "标志"), ts.ToArray());
                        gl.Title = "审批结点";
                        return gl;
                    });
                case ArgumentType.Source:

                    return UMC.Data.Reflection.Parse(this.AsyncDialog(name, g =>
                    {
                        var select = new UMC.Web.UISelectDialog();
                        foreach (var l in attr.ArgumentValue.Split(','))
                        {
                            select.Options.Add(l);
                        }
                        return select;
                    }), property.PropertyType);
                case ArgumentType.NVSource:

                    return UMC.Data.Reflection.Parse(this.AsyncDialog(name, g =>
                    {
                        var select = new UMC.Web.UISelectDialog();
                        var ts = attr.ArgumentValue.Split(',');
                        for (var l = 0; l < ts.Length; l += 2)// in attr.ArgumentValue.Split(','))
                        {
                            if (l + 1 < ts.Length)
                            {
                                select.Options.Add(ts[l], ts[l + 1]);
                            }
                            else
                            {
                                select.Options.Add(ts[l]);
                            }
                        }
                        return select;
                    }), property.PropertyType);

                default:
                    //if (attr.Type != null)
                    //{
                    //    var ob2js = attr.Type.GetCustomAttributes(typeof(DefaultDesignAttribute), false);
                    //    if (ob2js.Length > 0)
                    //    {
                    //        var attr2 = ob2js[0] as DefaultDesignAttribute;
                    //        this.Context.Response.Redirect(this.Context.Request.Model, attr2.ArgumentValue, this.Context.Request.Arguments, true);

                    //    }
                    //}

                    switch (property.PropertyType.FullName)
                    {
                        case "System.SByte":
                        case "System.Byte":
                        case "System.Int16":
                        case "System.UInt16":
                        case "System.Int32":
                        case "System.UInt32":
                        case "System.Int64":
                        case "System.UInt64":
                        case "System.Char":
                        case "System.Single":
                        case "System.Double":
                        case "System.Decimal":
                            return UMC.Data.Reflection.Parse(UIDialog.AsyncDialog(this.Context, name, g =>
                            {
                                var form = new UIFormDialog() { Title = attr.Caption };
                                form.AddNumber(attr.Caption, name, Convert.ToDecimal(value));
                                form.AddFooter(attr.Explain);
                                return form;// new UMC.Web.UINumberDialog(Convert.ToDecimal(value)) { Title = attr.Caption };

                            }), property.PropertyType);
                        case "System.Boolean":
                            return UMC.Data.Utility.Parse(this.AsyncDialog(name, g =>
                            {
                                var select = new UMC.Web.UISelectDialog();
                                select.Options.Add("是", "true");
                                select.Options.Add("否", "false");

                                return select;
                            }), false);
                        case "System.DateTime":
                            return UMC.Data.Reflection.Parse(UIDialog.AsyncDialog(this.Context, name, g =>
                            {

                                var form = new UIFormDialog() { Title = attr.Caption };
                                if (value != null)
                                {
                                    form.AddDate(attr.Caption, name, (DateTime)value);
                                }
                                else
                                {
                                    form.AddDate(attr.Caption, name, null);
                                }
                                form.AddFooter(attr.Explain);
                                return form;
                            }), property.PropertyType);
                        case "System.Guid":
                        case "System.String":
                            return UMC.Data.Reflection.Parse(UIDialog.AsyncDialog(this.Context, name, g =>
                            {
                                var form = new UIFormDialog() { Title = attr.Caption };
                                form.AddText(attr.Caption, name, (String)value);
                                form.AddFooter(attr.Explain);
                                return form;

                            }), property.PropertyType);
                        default:
                            if (property.PropertyType.IsEnum)
                            {
                                return UMC.Data.Reflection.Parse(this.AsyncDialog(name, g =>
                                {
                                    var ns = Enum.GetNames(property.PropertyType);

                                    var select = new UMC.Web.UISelectDialog();
                                    foreach (var n in ns)
                                    {
                                        select.Options.Add(n); ;
                                    }

                                    return select;

                                }), property.PropertyType);


                            }
                            else
                            {
                                var ob2js = property.PropertyType.GetCustomAttributes(typeof(DefaultDesignAttribute), false);
                                if (ob2js.Length > 0)
                                {
                                    var attr2 = ob2js[0] as DefaultDesignAttribute;
                                    this.Context.Response.Redirect(this.Context.Request.Model, attr2.ArgumentValue, this.Context.Request.Arguments, true);


                                }

                            }
                            return UMC.Data.Reflection.Parse(UIDialog.AsyncDialog(this.Context, name, g =>
                            {

                                var form = new UIFormDialog() { Title = attr.Caption };
                                form.AddText(attr.Caption, name, (String)value);
                                form.AddFooter(attr.Explain);
                                return form;
                                //return new UMC.Web.UITextDialog((String)value) { Title = attr.Caption };

                            }), property.PropertyType);
                    }

            }
            return null;

        }


        public override void ProcessActivity(WebRequest request, WebResponse response)
        {
            var Task = UMC.Data.Utility.UInt64Parse(this.AsyncDialog("Task", "0")).Value;


            this.DesignId = this.AsyncDialog("Id", "none");

            this.taskInstance = UMC.Data.JSON.Deserialize<TaskInstance>(TaskManager.Design(Task));

            var line = this.taskInstance.Lines.Find(g => g.Id == DesignId);
            if (line != null)
            {
                Setting(line);
                return;
            }

            var shape = this.taskInstance.Shapes.Find(g => g.Id == DesignId);
            if (shape != null)
            {
                Setting(shape);
                return;
            }
            var induce = this.taskInstance.Induces.Find(g => g.Id == DesignId);

            if (induce != null)
            {
                Setting(induce);
                return;
            }
            var registe = this.taskInstance.Registes.Find(g => g.Id == DesignId);

            if (registe != null)
            {
                Setting(registe);
                return;
            }
        }

    }
}